home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / gettext.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  16KB  |  628 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Internationalization and localization support.
  5.  
  6. This module provides internationalization (I18N) and localization (L10N)
  7. support for your Python programs by providing an interface to the GNU gettext
  8. message catalog library.
  9.  
  10. I18N refers to the operation by which a program is made aware of multiple
  11. languages.  L10N refers to the adaptation of your program, once
  12. internationalized, to the local language and cultural habits.
  13.  
  14. '''
  15. import locale
  16. import copy
  17. import os
  18. import re
  19. import struct
  20. import sys
  21. from errno import ENOENT
  22. __all__ = [
  23.     'NullTranslations',
  24.     'GNUTranslations',
  25.     'Catalog',
  26.     'find',
  27.     'translation',
  28.     'install',
  29.     'textdomain',
  30.     'bindtextdomain',
  31.     'dgettext',
  32.     'dngettext',
  33.     'gettext',
  34.     'ngettext']
  35. _default_localedir = os.path.join(sys.prefix, 'share', 'locale')
  36.  
  37. def test(condition, true, false):
  38.     '''
  39.     Implements the C expression:
  40.  
  41.       condition ? true : false
  42.  
  43.     Required to correctly interpret plural forms.
  44.     '''
  45.     if condition:
  46.         return true
  47.     else:
  48.         return false
  49.  
  50.  
  51. def c2py(plural):
  52.     '''Gets a C expression as used in PO files for plural forms and returns a
  53.     Python lambda function that implements an equivalent expression.
  54.     '''
  55.     
  56.     try:
  57.         StringIO = StringIO
  58.         import cStringIO
  59.     except ImportError:
  60.         StringIO = StringIO
  61.         import StringIO
  62.  
  63.     import token as token
  64.     import tokenize as tokenize
  65.     tokens = tokenize.generate_tokens(StringIO(plural).readline)
  66.     
  67.     try:
  68.         danger = _[1]
  69.     except tokenize.TokenError:
  70.         raise ValueError, 'plural forms expression error, maybe unbalanced parenthesis'
  71.  
  72.     if danger:
  73.         raise ValueError, 'plural forms expression could be dangerous'
  74.     
  75.     plural = plural.replace('&&', ' and ')
  76.     plural = plural.replace('||', ' or ')
  77.     expr = re.compile('\\!([^=])')
  78.     plural = expr.sub(' not \\1', plural)
  79.     expr = re.compile('(.*?)\\?(.*?):(.*)')
  80.     
  81.     def repl(x):
  82.         return 'test(%s, %s, %s)' % (x.group(1), x.group(2), expr.sub(repl, x.group(3)))
  83.  
  84.     stack = [
  85.         '']
  86.     for c in plural:
  87.         if c == '(':
  88.             stack.append('')
  89.             continue
  90.         (None, None)
  91.         if c == ')':
  92.             if len(stack) == 1:
  93.                 raise ValueError, 'unbalanced parenthesis in plural form'
  94.             
  95.             s = expr.sub(repl, stack.pop())
  96.             stack[-1] += '(%s)' % s
  97.             continue
  98.         stack[-1] += c
  99.     
  100.     plural = expr.sub(repl, stack.pop())
  101.     return eval('lambda n: int(%s)' % plural)
  102.  
  103.  
  104. def _expand_lang(locale):
  105.     normalize = normalize
  106.     import locale
  107.     locale = normalize(locale)
  108.     COMPONENT_CODESET = 1
  109.     COMPONENT_TERRITORY = 2
  110.     COMPONENT_MODIFIER = 4
  111.     mask = 0
  112.     pos = locale.find('@')
  113.     if pos >= 0:
  114.         modifier = locale[pos:]
  115.         locale = locale[:pos]
  116.         mask |= COMPONENT_MODIFIER
  117.     else:
  118.         modifier = ''
  119.     pos = locale.find('.')
  120.     if pos >= 0:
  121.         codeset = locale[pos:]
  122.         locale = locale[:pos]
  123.         mask |= COMPONENT_CODESET
  124.     else:
  125.         codeset = ''
  126.     pos = locale.find('_')
  127.     if pos >= 0:
  128.         territory = locale[pos:]
  129.         locale = locale[:pos]
  130.         mask |= COMPONENT_TERRITORY
  131.     else:
  132.         territory = ''
  133.     language = locale
  134.     ret = []
  135.     for i in range(mask + 1):
  136.         if not i & ~mask:
  137.             val = language
  138.             if i & COMPONENT_TERRITORY:
  139.                 val += territory
  140.             
  141.             if i & COMPONENT_CODESET:
  142.                 val += codeset
  143.             
  144.             if i & COMPONENT_MODIFIER:
  145.                 val += modifier
  146.             
  147.             ret.append(val)
  148.             continue
  149.     
  150.     ret.reverse()
  151.     return ret
  152.  
  153.  
  154. class NullTranslations:
  155.     
  156.     def __init__(self, fp = None):
  157.         self._info = { }
  158.         self._charset = None
  159.         self._output_charset = None
  160.         self._fallback = None
  161.         if fp is not None:
  162.             self._parse(fp)
  163.         
  164.  
  165.     
  166.     def _parse(self, fp):
  167.         pass
  168.  
  169.     
  170.     def add_fallback(self, fallback):
  171.         if self._fallback:
  172.             self._fallback.add_fallback(fallback)
  173.         else:
  174.             self._fallback = fallback
  175.  
  176.     
  177.     def gettext(self, message):
  178.         if self._fallback:
  179.             return self._fallback.gettext(message)
  180.         
  181.         return message
  182.  
  183.     
  184.     def lgettext(self, message):
  185.         if self._fallback:
  186.             return self._fallback.lgettext(message)
  187.         
  188.         return message
  189.  
  190.     
  191.     def ngettext(self, msgid1, msgid2, n):
  192.         if self._fallback:
  193.             return self._fallback.ngettext(msgid1, msgid2, n)
  194.         
  195.         if n == 1:
  196.             return msgid1
  197.         else:
  198.             return msgid2
  199.  
  200.     
  201.     def lngettext(self, msgid1, msgid2, n):
  202.         if self._fallback:
  203.             return self._fallback.lngettext(msgid1, msgid2, n)
  204.         
  205.         if n == 1:
  206.             return msgid1
  207.         else:
  208.             return msgid2
  209.  
  210.     
  211.     def ugettext(self, message):
  212.         if self._fallback:
  213.             return self._fallback.ugettext(message)
  214.         
  215.         return unicode(message)
  216.  
  217.     
  218.     def ungettext(self, msgid1, msgid2, n):
  219.         if self._fallback:
  220.             return self._fallback.ungettext(msgid1, msgid2, n)
  221.         
  222.         if n == 1:
  223.             return unicode(msgid1)
  224.         else:
  225.             return unicode(msgid2)
  226.  
  227.     
  228.     def info(self):
  229.         return self._info
  230.  
  231.     
  232.     def charset(self):
  233.         return self._charset
  234.  
  235.     
  236.     def output_charset(self):
  237.         return self._output_charset
  238.  
  239.     
  240.     def set_output_charset(self, charset):
  241.         self._output_charset = charset
  242.  
  243.     
  244.     def install(self, unicode = False, names = None):
  245.         import __builtin__ as __builtin__
  246.         if not unicode or self.ugettext:
  247.             pass
  248.         __builtin__.__dict__['_'] = self.gettext
  249.         if hasattr(names, '__contains__'):
  250.             if 'gettext' in names:
  251.                 __builtin__.__dict__['gettext'] = __builtin__.__dict__['_']
  252.             
  253.             if 'ngettext' in names:
  254.                 if not unicode or self.ungettext:
  255.                     pass
  256.                 __builtin__.__dict__['ngettext'] = self.ngettext
  257.             
  258.             if 'lgettext' in names:
  259.                 __builtin__.__dict__['lgettext'] = self.lgettext
  260.             
  261.             if 'lngettext' in names:
  262.                 __builtin__.__dict__['lngettext'] = self.lngettext
  263.             
  264.         
  265.  
  266.  
  267.  
  268. class GNUTranslations(NullTranslations):
  269.     LE_MAGIC = 0x950412DEL
  270.     BE_MAGIC = 0xDE120495L
  271.     
  272.     def _parse(self, fp):
  273.         '''Override this method to support alternative .mo formats.'''
  274.         unpack = struct.unpack
  275.         filename = getattr(fp, 'name', '')
  276.         self._catalog = catalog = { }
  277.         
  278.         self.plural = lambda n: int(n != 1)
  279.         buf = fp.read()
  280.         buflen = len(buf)
  281.         magic = unpack('<I', buf[:4])[0]
  282.         if magic == self.LE_MAGIC:
  283.             (version, msgcount, masteridx, transidx) = unpack('<4I', buf[4:20])
  284.             ii = '<II'
  285.         elif magic == self.BE_MAGIC:
  286.             (version, msgcount, masteridx, transidx) = unpack('>4I', buf[4:20])
  287.             ii = '>II'
  288.         else:
  289.             raise IOError(0, 'Bad magic number', filename)
  290.         for i in xrange(0, msgcount):
  291.             (mlen, moff) = unpack(ii, buf[masteridx:masteridx + 8])
  292.             mend = moff + mlen
  293.             (tlen, toff) = unpack(ii, buf[transidx:transidx + 8])
  294.             tend = toff + tlen
  295.             if mend < buflen and tend < buflen:
  296.                 msg = buf[moff:mend]
  297.                 tmsg = buf[toff:tend]
  298.             else:
  299.                 raise IOError(0, 'File is corrupt', filename)
  300.             if mlen == 0:
  301.                 lastk = None
  302.                 k = None
  303.                 for item in tmsg.splitlines():
  304.                     item = item.strip()
  305.                     if not item:
  306.                         continue
  307.                     
  308.                     if ':' in item:
  309.                         (k, v) = item.split(':', 1)
  310.                         k = k.strip().lower()
  311.                         v = v.strip()
  312.                         self._info[k] = v
  313.                         lastk = k
  314.                     elif lastk:
  315.                         self._info[lastk] += '\n' + item
  316.                     
  317.                     if k == 'content-type':
  318.                         self._charset = v.split('charset=')[1]
  319.                         continue
  320.                     if k == 'plural-forms':
  321.                         v = v.split(';')
  322.                         plural = v[1].split('plural=')[1]
  323.                         self.plural = c2py(plural)
  324.                         continue
  325.                 
  326.             
  327.             if '\x00' in msg:
  328.                 (msgid1, msgid2) = msg.split('\x00')
  329.                 tmsg = tmsg.split('\x00')
  330.                 for i in range(len(tmsg)):
  331.                     catalog[(msgid1, i)] = tmsg[i]
  332.                 
  333.             elif self._charset:
  334.                 msg = unicode(msg, self._charset)
  335.                 tmsg = unicode(tmsg, self._charset)
  336.             
  337.             catalog[msg] = tmsg
  338.             masteridx += 8
  339.             transidx += 8
  340.         
  341.  
  342.     
  343.     def gettext(self, message):
  344.         missing = object()
  345.         tmsg = self._catalog.get(message, missing)
  346.         if tmsg is missing:
  347.             if self._fallback:
  348.                 return self._fallback.gettext(message)
  349.             
  350.             return message
  351.         
  352.         if self._output_charset:
  353.             return tmsg.encode(self._output_charset)
  354.         elif self._charset:
  355.             return tmsg.encode(self._charset)
  356.         
  357.         return tmsg
  358.  
  359.     
  360.     def lgettext(self, message):
  361.         missing = object()
  362.         tmsg = self._catalog.get(message, missing)
  363.         if tmsg is missing:
  364.             if self._fallback:
  365.                 return self._fallback.lgettext(message)
  366.             
  367.             return message
  368.         
  369.         if self._output_charset:
  370.             return tmsg.encode(self._output_charset)
  371.         
  372.         return tmsg.encode(locale.getpreferredencoding())
  373.  
  374.     
  375.     def ngettext(self, msgid1, msgid2, n):
  376.         
  377.         try:
  378.             tmsg = self._catalog[(msgid1, self.plural(n))]
  379.             if self._output_charset:
  380.                 return tmsg.encode(self._output_charset)
  381.             elif self._charset:
  382.                 return tmsg.encode(self._charset)
  383.             
  384.             return tmsg
  385.         except KeyError:
  386.             if self._fallback:
  387.                 return self._fallback.ngettext(msgid1, msgid2, n)
  388.             
  389.             if n == 1:
  390.                 return msgid1
  391.             else:
  392.                 return msgid2
  393.         except:
  394.             n == 1
  395.  
  396.  
  397.     
  398.     def lngettext(self, msgid1, msgid2, n):
  399.         
  400.         try:
  401.             tmsg = self._catalog[(msgid1, self.plural(n))]
  402.             if self._output_charset:
  403.                 return tmsg.encode(self._output_charset)
  404.             
  405.             return tmsg.encode(locale.getpreferredencoding())
  406.         except KeyError:
  407.             if self._fallback:
  408.                 return self._fallback.lngettext(msgid1, msgid2, n)
  409.             
  410.             if n == 1:
  411.                 return msgid1
  412.             else:
  413.                 return msgid2
  414.         except:
  415.             n == 1
  416.  
  417.  
  418.     
  419.     def ugettext(self, message):
  420.         missing = object()
  421.         tmsg = self._catalog.get(message, missing)
  422.         if tmsg is missing:
  423.             if self._fallback:
  424.                 return self._fallback.ugettext(message)
  425.             
  426.             return unicode(message)
  427.         
  428.         return tmsg
  429.  
  430.     
  431.     def ungettext(self, msgid1, msgid2, n):
  432.         
  433.         try:
  434.             tmsg = self._catalog[(msgid1, self.plural(n))]
  435.         except KeyError:
  436.             if self._fallback:
  437.                 return self._fallback.ungettext(msgid1, msgid2, n)
  438.             
  439.             if n == 1:
  440.                 tmsg = unicode(msgid1)
  441.             else:
  442.                 tmsg = unicode(msgid2)
  443.         except:
  444.             n == 1
  445.  
  446.         return tmsg
  447.  
  448.  
  449.  
  450. def find(domain, localedir = None, languages = None, all = 0):
  451.     if localedir is None:
  452.         localedir = _default_localedir
  453.     
  454.     if languages is None:
  455.         languages = []
  456.         for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
  457.             val = os.environ.get(envar)
  458.             if val:
  459.                 languages = val.split(':')
  460.                 break
  461.                 continue
  462.         
  463.         if 'C' not in languages:
  464.             languages.append('C')
  465.         
  466.     
  467.     nelangs = []
  468.     for lang in languages:
  469.         for nelang in _expand_lang(lang):
  470.             if nelang not in nelangs:
  471.                 nelangs.append(nelang)
  472.                 continue
  473.         
  474.     
  475.     if all:
  476.         result = []
  477.     else:
  478.         result = None
  479.     for lang in nelangs:
  480.         if lang == 'C':
  481.             break
  482.         
  483.         mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
  484.         mofile_lp = os.path.join('/usr/share/locale-langpack', lang, 'LC_MESSAGES', '%s.mo' % domain)
  485.         if os.path.exists(mofile):
  486.             if all:
  487.                 result.append(mofile)
  488.             else:
  489.                 return mofile
  490.         
  491.         if os.path.exists(mofile_lp):
  492.             if all:
  493.                 result.append(mofile_lp)
  494.             else:
  495.                 return mofile_lp
  496.         all
  497.     
  498.     return result
  499.  
  500. _translations = { }
  501.  
  502. def translation(domain, localedir = None, languages = None, class_ = None, fallback = False, codeset = None):
  503.     if class_ is None:
  504.         class_ = GNUTranslations
  505.     
  506.     mofiles = find(domain, localedir, languages, all = 1)
  507.     if not mofiles:
  508.         if fallback:
  509.             return NullTranslations()
  510.         
  511.         raise IOError(ENOENT, 'No translation file found for domain', domain)
  512.     
  513.     result = None
  514.     for mofile in mofiles:
  515.         key = os.path.abspath(mofile)
  516.         t = _translations.get(key)
  517.         if t is None:
  518.             t = _translations.setdefault(key, class_(open(mofile, 'rb')))
  519.         
  520.         t = copy.copy(t)
  521.         if codeset:
  522.             t.set_output_charset(codeset)
  523.         
  524.         if result is None:
  525.             result = t
  526.             continue
  527.         result.add_fallback(t)
  528.     
  529.     return result
  530.  
  531.  
  532. def install(domain, localedir = None, unicode = False, codeset = None, names = None):
  533.     t = translation(domain, localedir, fallback = True, codeset = codeset)
  534.     t.install(unicode, names)
  535.  
  536. _localedirs = { }
  537. _localecodesets = { }
  538. _current_domain = 'messages'
  539.  
  540. def textdomain(domain = None):
  541.     global _current_domain
  542.     if domain is not None:
  543.         _current_domain = domain
  544.     
  545.     return _current_domain
  546.  
  547.  
  548. def bindtextdomain(domain, localedir = None):
  549.     if localedir is not None:
  550.         _localedirs[domain] = localedir
  551.     
  552.     return _localedirs.get(domain, _default_localedir)
  553.  
  554.  
  555. def bind_textdomain_codeset(domain, codeset = None):
  556.     if codeset is not None:
  557.         _localecodesets[domain] = codeset
  558.     
  559.     return _localecodesets.get(domain)
  560.  
  561.  
  562. def dgettext(domain, message):
  563.     
  564.     try:
  565.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  566.     except IOError:
  567.         return message
  568.  
  569.     return t.gettext(message)
  570.  
  571.  
  572. def ldgettext(domain, message):
  573.     
  574.     try:
  575.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  576.     except IOError:
  577.         return message
  578.  
  579.     return t.lgettext(message)
  580.  
  581.  
  582. def dngettext(domain, msgid1, msgid2, n):
  583.     
  584.     try:
  585.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  586.     except IOError:
  587.         if n == 1:
  588.             return msgid1
  589.         else:
  590.             return msgid2
  591.     except:
  592.         n == 1
  593.  
  594.     return t.ngettext(msgid1, msgid2, n)
  595.  
  596.  
  597. def ldngettext(domain, msgid1, msgid2, n):
  598.     
  599.     try:
  600.         t = translation(domain, _localedirs.get(domain, None), codeset = _localecodesets.get(domain))
  601.     except IOError:
  602.         if n == 1:
  603.             return msgid1
  604.         else:
  605.             return msgid2
  606.     except:
  607.         n == 1
  608.  
  609.     return t.lngettext(msgid1, msgid2, n)
  610.  
  611.  
  612. def gettext(message):
  613.     return dgettext(_current_domain, message)
  614.  
  615.  
  616. def lgettext(message):
  617.     return ldgettext(_current_domain, message)
  618.  
  619.  
  620. def ngettext(msgid1, msgid2, n):
  621.     return dngettext(_current_domain, msgid1, msgid2, n)
  622.  
  623.  
  624. def lngettext(msgid1, msgid2, n):
  625.     return ldngettext(_current_domain, msgid1, msgid2, n)
  626.  
  627. Catalog = translation
  628.